home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr48 / zip2obj.zip / XZIP.PAS < prev    next >
Pascal/Delphi Source File  |  1993-04-10  |  13KB  |  552 lines

  1. { XZIP.PAS - Explode data to memory routine (c) Wilbert van Leijen, 1991 }
  2.  
  3. Unit XZip;
  4.  
  5. Interface
  6.  
  7. Procedure Explode(Var InBuffer, OutBuffer; CompressedSize : Word);
  8.  
  9. Implementation
  10.  
  11. {$S-
  12.    USAGE NOTES:
  13.      -  Do not call Explode direct.  It is called by an linked in .OBJ
  14.         file, generated by ZIP2OBJ.
  15.      -  Maximum size of the uncompressed image is 64 kB
  16.      -  Memory requirements:  3k data, 10 k stack                       }
  17.  
  18. Const
  19.   MaxDictSize  = 8192;
  20.   BufSize      = 65520;                { Size of buffers for I/O }
  21.   MaxSFTreeSize = (1 shl 9)-1;
  22.   LitTreeRoot  = (1 shl 9)-1;
  23.   DistTreeRoot = (1 shl 7)-1;
  24.   LenTreeRoot  = (1 shl 7)-1;
  25.   CodeValue    : Array[1..8] of Byte = (
  26.     $01, $03, $07, $0F, $1F, $3F, $7F, $FF);
  27.  
  28. Type
  29.   BufType      = Array[0..BufSize] of Byte;
  30.   SFNode       = Record
  31.                    lChild        : Integer;
  32.                    rChild        : Integer;
  33.                  end;
  34.   SFBuildRec   = Record
  35.                    Len, Val    : Byte;
  36.                    Code        : Word;
  37.                  end;
  38.   SFBuildArray = Array[0..255] of SFBuildRec;
  39.  
  40. Var
  41.   SFLiteral    : Array[0..LitTreeRoot] of SFNode;
  42.   SFDist       : Array[0..DistTreeRoot] of SFNode;
  43.   SFLength     : Array[0..LenTreeRoot] of SFNode;
  44.   InfileBuf    : ^BufType;
  45.   DictSize     : Integer;
  46.   InBufPtr,
  47.   SFNextFree   : Word;
  48.   BitsLeft,                            { Unprocessed bits in input code buffer }
  49.   SaveByte,                            { Input code buffer - 1 byte long }
  50.   SFBuildIdx,                          { Index var for SFBuild array }
  51.   NumOfTrees   : Byte;                 { SF trees needed (2 or 3) }
  52.  
  53. Const
  54.   SFTreeRec    : Array[0..2] of Pointer = (
  55.                    @SFLiteral, @SFLength, @SFDist);
  56.   SFFreeRoot   : Array[0..2] of Word = (
  57.                    LitTreeRoot, LenTreeRoot, DistTreeRoot);
  58.  
  59. Function GetCode : Byte; Assembler;
  60.  
  61. ASM
  62.         PUSH   BX
  63.         PUSH   CX
  64.         PUSH   DX
  65.         MOV    DH, AL
  66.         MOV    AH, [BitsLeft]
  67.         MOV    DL, DH
  68.         XOR    CH, CH
  69.         XOR    BH, BH
  70.  
  71. @1:     CMP    DL, AH
  72.         JB     @2
  73.  
  74.         MOV    BL, AH
  75.         JMP    @3
  76.  
  77. @2:     MOV    BL, DL
  78. @3:     MOV    CL, DH
  79.         SUB    CL, DL
  80.         MOV    AL, Byte Ptr [BX+CodeValue-1]
  81.         AND    AL, [SaveByte]
  82.         SHL    AL, CL
  83.         OR     CH, AL
  84.         MOV    CL, BL
  85.         SHR    [SaveByte], CL
  86.         SUB    DL, BL
  87.         SUB    AH, BL
  88.         OR     AH, AH
  89.         JNE    @4
  90.  
  91.         LES    DI, [InfileBuf]
  92.         ADD    DI, [InBufPtr]
  93.         MOV    AL, ES:[DI]
  94.         MOV    [SaveByte], AL
  95.         INC    [InBufPtr]
  96.         MOV    AH, 8
  97.  
  98. @4:     OR     DL, DL
  99.         JNZ    @1
  100.  
  101.         MOV    [BitsLeft], AH
  102.         MOV    AL, CH
  103.         POP    DX
  104.         POP    CX
  105.         POP    BX
  106. end;  { GetCode }
  107.  
  108. Procedure AddSFSubTree(SFB : SFBuildRec; SFRoot : Word; Var SFTree);
  109.   Assembler;
  110.  
  111. ASM
  112.         MOV    DI, [SFNextFree]
  113.         PUSH   DS
  114.         PUSH   BX
  115.         PUSH   CX
  116.         PUSH   DX
  117.         MOV    BX, SFRoot
  118.         MOV    CL, SFB.Len
  119.         XOR    CH, CH
  120.         DEC    CX
  121.  
  122. @1:     JCXZ   @6
  123.         LDS    SI, SFTree
  124.         SHL    BX, 1
  125.         SHL    BX, 1
  126.         ADD    SI, BX
  127.         MOV    AX, SFB.Code
  128.         SHR    AX, CL
  129.         TEST   AX, 1
  130.         JZ     @3
  131.  
  132.         CMP    [SI+SFNode.rChild], -1
  133.         JNE    @2
  134.         MOV    [SI+SFNode.rChild], DI
  135.         DEC    DI
  136.  
  137. @2:     MOV    BX, [SI+SFNode.rChild]
  138.         JMP    @5
  139.  
  140. @3:     CMP    [SI+SFNode.lChild], -1
  141.         JNE    @4
  142.  
  143.         MOV    [SI.SFNode.lChild], DI
  144.         DEC    DI
  145.  
  146. @4:     MOV    BX, [SI+SFNode.lChild]
  147. @5:     DEC    CX
  148.         JMP    @1
  149.  
  150. @6:     LDS    SI, SFTree
  151.         SHL    BX, 1
  152.         SHL    BX, 1
  153.         ADD    SI, BX
  154.  
  155.         MOV    AL, SFB.Val
  156.         XOR    AH, AH
  157.         TEST   SFB.Code, 1
  158.         JZ     @7
  159.  
  160.         MOV    [SI+SFNode.rChild], AX
  161.         JMP    @8
  162.  
  163. @7:     MOV    [SI+SFNode.lChild], AX
  164.  
  165. @8:     POP    DX
  166.         POP    CX
  167.         POP    BX
  168.         POP    DS
  169.         MOV    [SFNextFree], DI
  170. end;  { AddSFSubTree }
  171.  
  172. Procedure ShellSort(Var SFB; n : Integer); Assembler;
  173.  
  174. Var
  175.   gap          : Integer;
  176.  
  177. ASM
  178.         PUSH   DS
  179.         PUSH   BX
  180.         LDS    DI, SFB
  181.         MOV    AX, n
  182.         SHR    AX, 1
  183.         MOV    gap, AX
  184.  
  185. @1:     CMP    gap, 0
  186.         JNG    @8
  187.  
  188.         MOV    DX, gap
  189.         INC    DX
  190.  
  191. @2:     MOV    AX, DX
  192.         SUB    AX, gap
  193.         MOV    CX, AX
  194.  
  195. @3:     CMP    CX, 0
  196.         JNG    @7
  197.  
  198.         MOV    SI, CX
  199.         ADD    SI, gap
  200.         MOV    BX, CX
  201.         DEC    BX
  202.         SHL    BX, 1
  203.         SHL    BX, 1
  204.         ADD    BX, DI
  205.         DEC    SI
  206.         SHL    SI, 1
  207.         SHL    SI, 1
  208.         ADD    SI, DI
  209.         MOV    AL, [BX+SFBuildRec.Len]
  210.         CMP    AL, [SI+SFBuildRec.Len]
  211.         JA     @5
  212.         MOV    AL, [BX+SFBuildRec.Len]
  213.         CMP    AL, [SI+SFBuildRec.Len]
  214.         JNE    @4
  215.         MOV    AL, [BX+SFBuildRec.Val]
  216.         CMP    AL, [SI+SFBuildRec.Val]
  217.         JA     @5
  218.  
  219. @4:     XOR    CX, CX
  220.         JMP    @6
  221.  
  222. @5:     MOV    AX, [BX]
  223.         PUSH   AX
  224.         MOV    AX, [SI]
  225.         MOV    [BX], AX
  226.         POP    AX
  227.         MOV    [SI], AX
  228.  
  229. @6:     MOV    AX, gap
  230.         SUB    CX, AX
  231.         JMP    @3
  232.  
  233. @7:     INC    DX
  234.         CMP    DX, n
  235.         JBE    @2
  236.  
  237.         MOV    AX, gap
  238.         SHR    AX, 1
  239.         MOV    gap, AX
  240.         JMP    @1
  241.  
  242. @8:     POP    BX
  243.         POP    DS
  244. end;  { ShellSort }
  245.  
  246. Procedure BuildSFTree(WhichTree : Byte; Var SFBuild : SFBuildArray);
  247.   Assembler;
  248.  
  249. Var
  250.   Code         : Word;
  251.  
  252. ASM
  253.         CMP     [NumOfTrees], 2
  254.         JNE     @1
  255.         INC     WhichTree
  256.  
  257. @1:     MOV     AL, WhichTree
  258.         XOR     AH, AH
  259.         MOV     DI, AX
  260.         SHL     DI, 1
  261.         MOV     AX, Word Ptr [DI+SFFreeRoot]
  262.         DEC     AX
  263.         MOV     [SFNextFree], AX
  264.         XOR     BL, BL
  265.         MOV     AL, 8
  266.         CALL    GetCode
  267.         MOV     BH, AL
  268.         XOR     CH, CH
  269.  
  270. @3:     MOV     AL, 8
  271.         CALL    GetCode
  272.         MOV     DL, AL
  273.         AND     AL, 15
  274.         INC     AL
  275.         MOV     DH, AL
  276.         MOV     CL, 4
  277.         SHR     DL, CL
  278.         XOR     CL, CL
  279.  
  280. @2:     MOV     AL, BL
  281.         XOR     AH, AH
  282.         SHL     AX, 1
  283.         SHL     AX, 1
  284.         LES     DI, SFBuild
  285.         ADD     DI, AX
  286.         MOV     ES:[DI+SFBuildRec.Len], DH
  287.         MOV     ES:[DI+SFBuildRec.Val], BL
  288.         INC     BL
  289.         INC     CL
  290.         CMP     DL, CL
  291.         JNB     @2
  292.  
  293.         INC     CH
  294.         CMP     CH, BH
  295.         JBE     @3
  296.  
  297.         LES     DI, SFBuild
  298.         PUSH    ES
  299.         PUSH    DI
  300.         MOV     AL, BL
  301.         DEC     AL
  302.         XOR     AH, AH
  303.         INC     AX
  304.         PUSH    AX
  305.         CALL    ShellSort
  306.         XOR     AX, AX
  307.         MOV     Code, AX
  308.         XOR     CH, CH
  309.         XOR     DX, DX
  310.         DEC     BL
  311.         XOR     BH, BH
  312.         OR      BX, BX
  313.         JB      @5
  314.         JMP     @6
  315.  
  316. @8:     DEC     BX
  317.  
  318. @6:     ADD     Code, DX
  319.         MOV     AX, BX
  320.         SHL     AX, 1
  321.         SHL     AX, 1
  322.         LES     DI, SFBuild
  323.         ADD     DI, AX
  324.         MOV     AL, ES:[DI+SFBuildRec.Len]
  325.         CMP     AL, CH
  326.         JE      @7
  327.         MOV     CH, ES:[DI+SFBuildRec.Len]
  328.         MOV     CL, 16
  329.         SUB     CL, CH
  330.         MOV     DX, 1
  331.         SHL     DX, CL
  332.  
  333. @7:     MOV     CL, 16
  334.         SUB     CL, ES:[DI+SFBuildRec.Len]
  335.         MOV     AX, Code
  336.         SHR     AX, CL
  337.         MOV     ES:[DI+SFBuildRec.Code], AX
  338.         PUSH    Word Ptr ES:[DI+SFBuildRec.Code]
  339.         PUSH    Word Ptr ES:[DI+SFBuildRec.Len]
  340.         MOV     AL, WhichTree
  341.         XOR     AH, AH
  342.         MOV     DI, AX
  343.         SHL     DI, 1
  344.         PUSH    Word Ptr [DI+SFFreeRoot]
  345.         SHL     DI, 1
  346.         LES     DI, DWord Ptr [DI+SFTreeRec]
  347.         PUSH    ES
  348.         PUSH    DI
  349.         CALL    AddSFSubTree
  350.         OR      BX, BX
  351.         JNZ     @8
  352. @5:
  353. end;  { BuildSFTree }
  354.  
  355. Function DecodeSFData : Byte; Assembler;
  356.  
  357. ASM
  358.         PUSH   BX
  359.         PUSH   CX
  360.         PUSH   DX
  361.         MOV    CX, AX
  362.         INC    AX
  363.         SHR    AX, 1
  364.         DEC    AX
  365.         MOV    DX, AX
  366.  
  367. @1:     MOV    AL, 1
  368.         CALL   GetCode
  369.         MOV    DI, SI
  370.  
  371.         MOV    BX, CX
  372.         SHL    BX, 1
  373.         SHL    BX, 1
  374.         ADD    DI, BX
  375.         TEST   AL, 1
  376.         JZ     @2
  377.  
  378.         INC    DI
  379.         INC    DI
  380. @2:     MOV    CX, [DI]
  381.         CMP    CX, DX
  382.         JA     @1
  383.  
  384.         XCHG   AX, CX
  385.         POP    DX
  386.         POP    CX
  387.         POP    BX
  388. end;  { DecodeSFData }
  389.  
  390. Procedure Explode(Var InBuffer, OutBuffer; CompressedSize : Word);
  391.   Assembler;
  392.  
  393. Var
  394.   Dictionary   : Array[0..MaxDictSize-1] of Byte;
  395.   SFBuild      : SFBuildArray;
  396.  
  397. ASM
  398.         DEC    CompressedSize
  399.         MOV    [InBufPtr], 1
  400.         LES    DI, InBuffer
  401.         MOV    Word Ptr [InfileBuf], DI
  402.         MOV    Word Ptr [InfileBuf+2], ES
  403.         MOV    AL, ES:[DI]
  404.         MOV    [SaveByte], AL
  405.         MOV    [BitsLeft], 8
  406.         MOV    AX, ES:[DI-2]
  407.         MOV    CX, 4096
  408.         TEST   AX, 2
  409.         JZ     @1
  410.         SHL    CX, 1
  411.  
  412. @1:     DEC    CX
  413.         MOV    [DictSize], CX
  414.         MOV    CL, 2
  415.         TEST   AX, 4
  416.         JZ     @2
  417.         INC    CL
  418.  
  419. @2:     MOV    [NumOfTrees], CL
  420.         CLD
  421.         XOR    AX, AX
  422.         PUSH   SS
  423.         POP    ES
  424.         LEA    DI, Word Ptr Dictionary
  425.         MOV    CX, (MaxDictSize / 2)
  426.         REP    STOSW
  427.         DEC    AX    
  428.         PUSH   DS
  429.         POP    ES
  430.         MOV    DI, Offset SFLength
  431.         MOV    CX, 2*(LenTreeRoot+1)
  432.         REP    STOSW
  433.         MOV    DI, Offset SFDist
  434.         MOV    CX, 2*(DistTreeRoot+1)
  435.         REP    STOSW
  436.         MOV    DI, Offset SFLiteral
  437.         MOV    CX, 2*(LitTreeRoot+1)
  438.         REP    STOSW
  439.  
  440.         XOR    AX, AX
  441.         LEA    DI, SFBuild
  442.         PUSH   AX
  443.         PUSH   SS
  444.         PUSH   DI
  445.         CALL   BuildSFTree
  446.         MOV    AL, 1
  447.         LEA    DI, SFBuild
  448.         PUSH   AX
  449.         PUSH   SS
  450.         PUSH   DI
  451.         CALL   BuildSFTree
  452.         CMP    [NumOfTrees], 3
  453.         JNE    @3
  454.         MOV    AL, 2
  455.         LEA    DI, SFBuild
  456.         PUSH   AX
  457.         PUSH   SS
  458.         PUSH   DI
  459.         CALL   BuildSFTree
  460.  
  461. @3:     XOR    BX, BX
  462.         XOR    DX, DX
  463. @4:     MOV    AL, 1
  464.         CALL   GetCode
  465.         OR     AL, AL
  466.         JZ     @7
  467.  
  468.         CMP    [NumOfTrees], 3
  469.         JNE    @5
  470.  
  471.         MOV    SI, Offset SFLiteral
  472.         MOV    AX, LitTreeRoot
  473.         CALL   DecodeSFData
  474.         JMP    @6
  475.  
  476. @5:     MOV    AL, 8
  477.         CALL   GetCode
  478.  
  479. @6:     LES    DI, OutBuffer
  480.         ADD    DI, DX
  481.         STOSB
  482.         INC    DX
  483.         MOV    SI, BX
  484.         MOV    Byte Ptr [SI+Dictionary], AL
  485.         INC    BX
  486.         AND    BX, [DictSize]
  487.         JMP    @11
  488.  
  489. @7:     MOV    CX, 6
  490.         CMP    [NumOfTrees], 3
  491.         JNE    @8
  492.  
  493.         INC    CX
  494. @8:     MOV    AL, CL
  495.         CALL   GetCode
  496.         XOR    AH, AH
  497.         PUSH   AX
  498.         MOV    SI, Offset SFDist
  499.         MOV    AX, DistTreeRoot
  500.         CALL   DecodeSFData
  501.         XOR    AH, AH
  502.         SHL    AX, CL
  503.         POP    CX
  504.         OR     AX, CX
  505.         PUSH   AX
  506.         MOV    SI, Offset SFLength
  507.         MOV    AX, LenTreeRoot
  508.         CALL   DecodeSFData
  509.         XOR    AH, AH
  510.         MOV    CX, AX
  511.         CMP    CX, 63
  512.         JNE    @9
  513.  
  514.         MOV    AL, 8
  515.         CALL   GetCode
  516.         XOR    AH, AH
  517.         ADD    CX, AX
  518.  
  519. @9:     MOV    AL, [NumOfTrees]
  520.         XOR    AH, AH
  521.         ADD    CX, AX
  522.         POP    AX
  523.         MOV    SI, BX
  524.         SUB    SI, AX
  525.         DEC    SI
  526.         CMP    SI, 0
  527.         JGE    @10
  528.  
  529.         ADD    SI, [DictSize]
  530.         INC    SI
  531.  
  532. @10:    MOV    AL, Byte Ptr [SI+Dictionary]
  533.         LES    DI, OutBuffer
  534.         ADD    DI, DX
  535.         STOSB
  536.         INC    DX
  537.         MOV    DI, BX
  538.         MOV    Byte Ptr [DI+Dictionary], AL
  539.         INC    BX
  540.         AND    BX, [DictSize]
  541.         INC    SI
  542.         AND    SI, [DictSize]
  543.         DEC    CX
  544.         OR     CX, CX
  545.         JNZ    @10
  546.  
  547. @11:    MOV    AX, [InBufPtr]
  548.         CMP    AX, CompressedSize
  549.         JBE    @4
  550. end;  { Explode }
  551.  
  552. end.  { XZip }